/* 2014/10/24 */
package com.cosmos.quartz.control;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.quartz.Trigger.TriggerState;

public class JobControlReport {

	private static final String SEPARATOR = ",";
	private static final String JOB_PREFIX = "job:";
	private static final String PREVIOUS_TIME_PREFIX = "previousFire:";
	private static final String NEXT_TIME_PREFIX = "nextFire:";
	private static final String REPEAT_INTERVAL_PREFIX = "interval:";
	private static final String TRIGGER_STATE_PREFIX = "state:";
	private static final String CURRENT_TIME_PREFIX = "now:";
	
	private static final String NULL_DATE_TEXT = "N/A";
	private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
	
	private String jobName;
	private Date previousFireTime;
	private Date nextFireTime;
	private long repeatInterval;
	private TriggerState triggerState;
	private Date currentTime;

	/**
	 * Parses text to produce JobControlReport object.
	 */
	public static JobControlReport parse(String text) throws IllegalArgumentException, ParseException,
		NumberFormatException, IllegalArgumentException {		
		if (text == null) {
			throw new IllegalArgumentException("Text to be parsed cannot be null.");
		}
		
		JobControlReport report = new JobControlReport();
		String[] properties = text.split(",");
		
		for (String property : properties) {
			if (property.startsWith(JOB_PREFIX)) {
				report.jobName = property.substring(JOB_PREFIX.length());
			} else if (property.startsWith(PREVIOUS_TIME_PREFIX)) {
				String dateText = property.substring(PREVIOUS_TIME_PREFIX.length());
				if (NULL_DATE_TEXT.equals(dateText)) {
					report.previousFireTime = null;
				} else {
					report.previousFireTime = TIME_FORMAT.parse(dateText);
				}
			} else if (property.startsWith(NEXT_TIME_PREFIX)) {
				String dateText = property.substring(NEXT_TIME_PREFIX.length());
				if (NULL_DATE_TEXT.equals(dateText)) {
					report.nextFireTime = null;
				} else {
					report.nextFireTime = TIME_FORMAT.parse(dateText);
				}
			} else if (property.startsWith(REPEAT_INTERVAL_PREFIX)) {
				String longText = property.substring(REPEAT_INTERVAL_PREFIX.length());
				report.repeatInterval = Long.parseLong(longText);
			} else if (property.startsWith(TRIGGER_STATE_PREFIX)) {
				String stateText = property.substring(TRIGGER_STATE_PREFIX.length());
				report.triggerState = TriggerState.valueOf(stateText);
			} else if (property.startsWith(CURRENT_TIME_PREFIX)) {
				String dateText = property.substring(CURRENT_TIME_PREFIX.length());
				report.currentTime = TIME_FORMAT.parse(dateText);
			} else {
				throw new IllegalArgumentException("Report format is not correct.");
			}
		}
		
		return report;
	}
	
	@Override
	public String toString() {
		StringBuilder result = new StringBuilder();
		result.append(JOB_PREFIX);
		result.append(jobName);	
		
		result.append(SEPARATOR);
		result.append(PREVIOUS_TIME_PREFIX);		
		result.append(formatDate(previousFireTime));
		
		result.append(SEPARATOR);
		result.append(NEXT_TIME_PREFIX);		
		result.append(formatDate(nextFireTime));
		
		result.append(SEPARATOR);
		result.append(REPEAT_INTERVAL_PREFIX);
		result.append(repeatInterval);
		
		result.append(SEPARATOR);
		result.append(TRIGGER_STATE_PREFIX);
		result.append(triggerState.toString());
		
		result.append(SEPARATOR);
		result.append(CURRENT_TIME_PREFIX);
		result.append(formatDate(currentTime));
		
		return result.toString();
	}
	
	private String formatDate(Date time) {
		if (time != null) {
			return TIME_FORMAT.format(time);
		} else {
			return NULL_DATE_TEXT;
		}
	}

	public String getJobName() {
		return jobName;
	}

	public void setJobName(String jobName) {
		this.jobName = jobName;
	}

	public Date getPreviousFireTime() {
		return previousFireTime;
	}

	public void setPreviousFireTime(Date previousFireTime) {
		this.previousFireTime = previousFireTime;
	}

	public Date getNextFireTime() {
		return nextFireTime;
	}

	public void setNextFireTime(Date nextFireTime) {
		this.nextFireTime = nextFireTime;
	}

	public long getRepeatInterval() {
		return repeatInterval;
	}

	public void setRepeatInterval(long repeatInterval) {
		this.repeatInterval = repeatInterval;
	}

	public TriggerState getTriggerState() {
		return triggerState;
	}

	public void setTriggerState(TriggerState triggerState) {
		this.triggerState = triggerState;
	}
	
	public Date getCurrentTime() {
		return currentTime;
	}

	public void setCurrentTime(Date currentTime) {
		this.currentTime = currentTime;
	}
	
}
